package com.heima.article.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.heima.article.entity.ApArticle;
import com.heima.article.entity.ApArticleContent;
import com.heima.article.entity.JudgmentBehavior;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.service.ApArticleContentService;
import com.heima.article.service.ApArticleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.article.service.FreemarkerService;
import com.heima.common.dtos.ResponseResult;
import com.heima.common.enums.BehaviorEnum;
import com.heima.common.util.BeanHelper;
import com.heima.common.util.JsonUtils;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.article.dtos.ArticleLoadDTO;
import com.heima.model.media.dtos.WmNewsResultDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigurationPackage;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 文章信息表，存储已发布的文章 服务实现类
 * </p>
 *
 * @author HM
 * @since 2023-05-25
 */
@Service
public class ApArticleServiceImpl extends ServiceImpl<ApArticleMapper, ApArticle> implements ApArticleService {

    @Autowired
    private ApArticleContentService contentService;

    @Autowired
    private FreemarkerService freemarkerService;
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public ArticleDto findById(long articleId) {
        return this.baseMapper.findById(articleId);
    }

    @Override
    public List<ApArticle> findLatestArticleIn(int days) {

        LocalDateTime startTime = LocalDate.now().minusDays(days).atStartOfDay();
        //默认的过滤条件
        LambdaQueryWrapper<ApArticle> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(ApArticle::getIsDelete,false);
        queryWrapper.eq(ApArticle::getIsDown,false);
        //发布时间
        queryWrapper.ge(ApArticle::getPublishTime,startTime);

        return this.list(queryWrapper);
    }

    /**
     * 回显  点赞  喜欢  关注  收藏
     * @param like
     * @param unLike
     * @param collection
     * @param follow
     * @return
     */
    @Override
    public ResponseResult judgmentBehavior(String collection,String like, String follow) {

        JudgmentBehavior behavior=new JudgmentBehavior();

      //判断是否有点赞
        if (!StringUtils.isEmpty(like.toString())){
            //转换成Integer类型
            Integer likes= Integer.valueOf(like.toString());
            //likes值大于0
            if (likes> BehaviorEnum.ZERO.getCode()){
                //大于零表示点赞
                behavior.setIslike(BehaviorEnum.RIGHT.getBr());
            }else {
                //小于零表示不不点赞
                behavior.setIslike(BehaviorEnum.WRONG.getBr());
            }
        }


        //判断是否有收藏
        if (!StringUtils.isEmpty(collection.toString())){
            //转换成Integer类型
            Integer collections= Integer.valueOf(collection.toString());
            //likes值大于0
            if (collections> BehaviorEnum.ZERO.getCode()){
                //大于零表示收藏
                behavior.setIscollection(BehaviorEnum.RIGHT.getBr());
            }else {
                //小于零表示未收藏
                behavior.setIscollection(BehaviorEnum.WRONG.getBr());
            }

        }
       /* //判断是否有
        if (!StringUtils.isEmpty(unLike.toString())){
            //转换成Integer类型
            Integer unLikes= Integer.valueOf(unLike.toString());
            //likes值大于0
            if (unLikes> BehaviorEnum.ZERO.getCode()){
                //大于零表示点赞
                behavior.setIsUnlike(BehaviorEnum.RIGHT.getBr());
            }else {
                //小于零表示未点赞
                behavior.setIsUnlike(BehaviorEnum.WRONG.getBr());
            }
        }*/
        //判断是否有关注
        if (!StringUtils.isEmpty(follow.toString())){
            //转换成Integer类型
            Integer follows= Integer.valueOf(follow.toString());
            //likes值大于0
            if (follows> BehaviorEnum.ZERO.getCode()){
                //大于零表示关注
                behavior.setIsfollow(BehaviorEnum.RIGHT.getBr());
            }else {
                //小于零表示关注
                behavior.setIsfollow(BehaviorEnum.WRONG.getBr());
            }

        }

        return ResponseResult.ok(behavior);
    }

    @Override
    public List<ArticleDto> findByPage(int page, int size) {
        Page<ApArticle>  ipage = new Page<>(page, size);
        return this.baseMapper.findByPage(ipage);
    }

    @Override
    public List<ApArticle> load(ArticleLoadDTO dto) {
        return loadmore(dto);
    }

    @Override
    public List<ApArticle> loadmore(ArticleLoadDTO dto) {

        // 如果是推荐频道，查询redis的zset
        if(dto.getChannelId() != null && dto.getChannelId() == 0){
            return loadHotArticles(dto);
        }
        // 比当前页，最小的还要小
        LambdaQueryWrapper<ApArticle> queryWrapper = new LambdaQueryWrapper<>();
        // 默认的过滤条件
        queryWrapper.eq(ApArticle::getIsDown, false);
        queryWrapper.eq(ApArticle::getIsDelete, false);
        queryWrapper.lt(ApArticle::getPublishTime, dto.getMinTime());
        queryWrapper.eq(dto.getChannelId()!=null && dto.getChannelId()>0, ApArticle::getChannelId, dto.getChannelId());
        // 添加发布时间的排序
        queryWrapper.orderByDesc(ApArticle::getPublishTime);
        // limit ?
        Page<ApArticle> ipgae= new Page<>(1, dto.getSize());
        // 查询
        Page<ApArticle> pageResponse = this.page(ipgae, queryWrapper);
        return pageResponse.getRecords();
    }
    //TODO zset手机端分页
    private List<ApArticle> loadHotArticles(ArticleLoadDTO dto) {
        Set<String> articleaIds = redisTemplate.boundZSetOps(ApHotArticlesServiceImpl.PREFIX).reverseRangeByScore(0, Double.MAX_VALUE);
        if (CollectionUtils.isEmpty(articleaIds)){
            return new ArrayList<>();
        }
        List<ApArticle> result=new ArrayList<>();
        for (String articleaId : articleaIds) {
            //TODO article 上下架的时候,redis需要同步上下架
            String json = redisTemplate.boundValueOps(ApHotArticlesServiceImpl.PREFIX + ":" + articleaId).get();
            if (!StringUtils.isEmpty(json)){
                ApArticle article = JsonUtils.toBean(json, ApArticle.class);
                result.add(article);
            }
        }
        return result;
    }

    @Override
    public List<ApArticle> loadnew(ArticleLoadDTO dto) {
        // 如果是推荐频道，查询redis的zset
        if(dto.getChannelId() != null && dto.getChannelId() == 0){
            return loadHotArticles(dto);
        }
        // 比当前页最大的数据还要大
        LambdaQueryWrapper<ApArticle> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ApArticle::getIsDown, false);
        queryWrapper.eq(ApArticle::getIsDelete, false);
        queryWrapper.gt(ApArticle::getPublishTime, dto.getMaxTime());
        queryWrapper.eq(dto.getChannelId()!=null && dto.getChannelId()>0, ApArticle::getChannelId, dto.getChannelId());
        // 添加发布时间的排序
        queryWrapper.orderByDesc(ApArticle::getPublishTime);
        // limit ?
        Page<ApArticle> ipgae= new Page<>(1, dto.getSize());
        // 查询
        Page<ApArticle> pageResponse = this.page(ipgae, queryWrapper);
        return pageResponse.getRecords();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createArticle(WmNewsResultDTO dto) {
        // 跟据自媒体文章的id查询article，有就更新，没有就插入
        // 保存ap_article，saveOrUpdate
        Long articleId = saveArticle(dto);
        // 保存ap_article_content，saveOrUpdate
        contentService.saveContent(articleId, dto.getContent());
        // 异步 生成静态的html，上传minio，回填url地址到ap_article
        freemarkerService.asyncContentStatic(articleId, dto.getContent());
        return articleId;
    }

    private Long saveArticle(WmNewsResultDTO dto) {
        LambdaQueryWrapper<ApArticle> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ApArticle::getWmNewsId, dto.getId());
        ApArticle articleDB = this.getOne(queryWrapper);
        Long articleId = 0L;
        if(articleDB == null){
            // insert
            ApArticle toBeInsert = BeanHelper.copyProperties(dto, ApArticle.class);
            toBeInsert.setId(null);
            toBeInsert.setAuthorId(123);//TODO 根据wmUserId查询author数据
            toBeInsert.setAuthorName("123");
            toBeInsert.setLayout(dto.getType());
            toBeInsert.setFlag(0);
            toBeInsert.setLikes(0L);
            toBeInsert.setComments(0L);
            toBeInsert.setCollection(0L);
            toBeInsert.setViews(0L);
            toBeInsert.setCreatedTime(new Date());
            toBeInsert.setIsComment(true);
            toBeInsert.setIsForward(true);
            toBeInsert.setIsDelete(false);
            toBeInsert.setIsDown(false);
            toBeInsert.setWmNewsId(dto.getId());
            this.save(toBeInsert);
            articleId = toBeInsert.getId();
        }else{
            // update
            ApArticle toBeUpdate =  BeanHelper.copyProperties(dto, ApArticle.class);
            toBeUpdate.setId(articleDB.getId());
            toBeUpdate.setLayout(dto.getType());
            this.updateById(toBeUpdate);
            articleId = articleDB.getId();
        }
        return articleId;
    }

}
